package com.ktg.mes.pro.service.impl;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ktg.common.core.domain.model.SqlResult;
import com.ktg.common.utils.DateUtils;
import com.ktg.common.utils.SecurityUtils;
import com.ktg.common.utils.StringUtils;
import com.ktg.mes.md.domain.MdItem;
import com.ktg.mes.md.service.IMdItemService;
import com.ktg.mes.md.service.IMesScalesOrderItemService;
import com.ktg.mes.pro.domain.*;
import com.ktg.mes.pro.service.IProRouteProcessService;
import com.ktg.mes.pro.service.IProTaskChangeVersionService;
import com.ktg.mes.pro.service.IProWorkorderService;
import com.ktg.mes.rec.domain.RecLnspectionRecord;
import com.ktg.mes.unit.other.SQLListenerInterface;
import com.ktg.mes.unit.other.SQLListenerType;
import com.ktg.mes.unit.other.ZLServiceIml;
import com.ktg.mes.wm.domain.WmItemRecptLine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ktg.mes.pro.mapper.ProTaskMapper;
import com.ktg.mes.pro.service.IProTaskService;

/**
 * 生产任务Service业务层处理
 *
 * @author yinjinlu
 * @date 2022-05-14
 */
@Service
public class ProTaskServiceImpl  extends ZLServiceIml<ProTaskMapper, ProTask> implements IProTaskService {

    @Autowired
    private IProRouteProcessService proRouteProcessService;

    @Autowired
    private IMesScalesOrderItemService mesScalesOrderItemService;

    @Autowired
    private IProWorkorderService proWorkorderService;

    @Autowired
    private IProTaskChangeVersionService proTaskChangeVersionService;

    @Autowired
    private IMdItemService mdItemService;

    @Override
    public ProTask findOld(ProTask model) {
        return getById(model.getTaskId());
    }

    @Override
    public List<ProTask> getFromIds(Serializable[] ids) {
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.in("task_id",ids);
        return list(queryWrapper);
    }

    /**
     * 查询生产任务
     *
     * @param taskId 生产任务主键
     * @return 生产任务
     */
    @Override
    public ProTask selectProTaskByTaskId(Long taskId)
    {
        return getBaseMapper().selectProTaskByTaskId(taskId);
    }

    /**
     * 查询生产任务列表
     *
     * @param proTask 生产任务
     * @return 生产任务
     */
    @Override
    public List<ProTask> selectProTaskList(ProTask proTask)
    {
        return getBaseMapper().selectProTaskList(proTask);
    }

    /**
     * 新增生产任务
     *
     * @param proTask 生产任务
     * @return 结果
     */
    @Override
    public SqlResult insertProTask(ProTask proTask)
    {
        try {
            //判断是否需要删除
            ProTask task  = getBaseMapper().isDeleteTask(proTask);

            if(ObjectUtils.isNotNull(task)){
                //如果位置的任务已经生产，或者已经完成等，则不能替换排产
                if (!task.getStatus().equals("0") && !task.getStatus().equals("领料")){
                    return SqlResult.error("替换订单已经开始生产，不能再编辑",null);
                }
                if (!StringUtils.isEmpty(task.getTaskStatus()) && !task.getTaskStatus().equals("已排产")){
                    return SqlResult.error("替换订单已经开始"+task.getTaskStatus()+"，不能再编辑",null);
                }

                getBaseMapper().deleteProTaskByTaskId(task.getTaskId());
                //跟新销售订单完成数量
                if (task.getScaleId() != null){
                    mesScalesOrderItemService.addCount(task.getScaleId(),-task.getQuantity().doubleValue(),0.0,0.0);
                }
                task.setQuantity(BigDecimal.valueOf(0));
                proWorkorderService.setStatusAfterTaskChange(task);
            }
            if (proTask.getScaleId() != null){
                mesScalesOrderItemService.addCount(proTask.getScaleId(),proTask.getQuantity().doubleValue(),0.0,0.0);
            }

            proTask.setCreateTime(DateUtils.getNowDate());
            if (proTask.getTaskId() != null){
                ProTask oldProTask = getById(proTask.getTaskId());
                updateTaskChangeVersion(oldProTask);
            }
            updateTaskChangeVersion(proTask);
            boolean sss = save(proTask);
            if (sss){
                proWorkorderService.setStatusAfterTaskChange(proTask);
            }
            return sss? SqlResult.ok(null,null):SqlResult.error("替换订单已经排产入库，不能再编辑",null);
        }catch (Exception e){
            e.printStackTrace();
            return SqlResult.ok(this.getClass().toString(),null);
        }
    }


    /**
     * 修改生产任务
     *
     * @param proTask 生产任务
     * @return 结果
     */
    @Override
    public SqlResult updateProTask(ProTask proTask)
    {
        try {
            if(StringUtils.isNotNull(proTask.getIsDelete())){
                //判断是否需要删除
                ProTask task  = getBaseMapper().isDeleteTask(proTask);

                if(ObjectUtils.isNotNull(task)){
                    //如果位置的任务已经生产，或者已经完成等，则不能替换排产
                    if (!task.getStatus().equals("0") && !task.getStatus().equals("领料")){
                        return SqlResult.error("替换订单已经开始生产，不能再编辑",null);
                    }
                    if (!StringUtils.isEmpty(task.getTaskStatus()) && !task.getTaskStatus().equals("已排产")){
                        return SqlResult.error("替换订单已经开始"+task.getTaskStatus()+"，不能再编辑",null);
                    }

                    getBaseMapper().deleteProTaskByTaskId(task.getTaskId());
                    task.setQuantity(BigDecimal.valueOf(0));
                    //跟新销售订单完成数量
                    if (task.getScaleId() != null){
                        mesScalesOrderItemService.addCount(task.getScaleId(),-task.getQuantity().doubleValue(),0.0,0.0);
                    }
                    if (proTask.getScaleId() != null){
                        mesScalesOrderItemService.addCount(proTask.getScaleId(),proTask.getQuantity().doubleValue(),0.0,0.0);
                    }
                    task.setQuantity(BigDecimal.valueOf(0));
                    proWorkorderService.setStatusAfterTaskChange(task);
                }
            }

            proTask.setUpdateBy(SecurityUtils.getUsername());
            proTask.setUpdateTime(DateUtils.getNowDate());
            if (proTask.getTaskId() != null){
                ProTask oldProTask = getById(proTask.getTaskId());
                updateTaskChangeVersion(oldProTask);
            }
            updateTaskChangeVersion(proTask);
            proTask.setUpdateTime(new Date());
            if (proTask.getTaskStatus().equals(ProTask.taskStatusFinish)
                    || proTask.getTaskStatus().equals(ProTask.taskStatusConcessionAcceptance)
                    || proTask.getTaskStatus().equals(ProTask.taskStatusInWarehouse)
            ){
                proTask.setEndTime(new Date());
                proTask.setIsFinish("Y");
            }else {
                proTask.setIsFinish("N");
            }
            boolean sss = this.updateById(proTask);
            if (sss){
                proWorkorderService.setStatusAfterTaskChange(proTask);
            }

            return sss? SqlResult.ok(null,null):SqlResult.error("替换订单已经排产入库，不能再编辑",null);
        }catch (Exception e){
            e.printStackTrace();;
            return SqlResult.error(this.getClass().toString(),e);
        }
    }


    private void  updateTaskChangeVersion(ProTask proTask){
        try{
            if (proTask == null){
                return;
            }
            String dateKey = DateUtils.parseDateToStr("YYYYMMdd120000",proTask.getProductionDate());
            String dateStr = DateUtils.parseDateToStr("YYYY-MM-dd 12:00:00",proTask.getProductionDate());
            ProTaskChangeVersion proTaskChangeVersion = proTaskChangeVersionService.getById(dateKey);
            if (proTaskChangeVersion != null){
                proTaskChangeVersion.setVersion(proTaskChangeVersion.getVersion()+1);
                proTaskChangeVersionService.updateById(proTaskChangeVersion);
            }else {
                ProTaskChangeVersion proTaskChangeVersion1 = new ProTaskChangeVersion();
                proTaskChangeVersion1.setVersion(1);
                proTaskChangeVersion1.setRecordId(dateKey);
                proTaskChangeVersion1.setMdate(DateUtils.parseDate(dateStr));
                proTaskChangeVersionService.insert(proTaskChangeVersion1);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

    }


    /**
     * 批量删除生产任务
     *
     * @param taskIds 需要删除的生产任务主键
     * @return 结果
     */
    @Override
    public SqlResult deleteProTaskByTaskIds(Long[] taskIds)
    {
        try {
            List<ProTask> taskList = new ArrayList<>();
            for (int i = 0;i < taskIds.length;i++){
                ProTask task = getById(taskIds[i]);
                if (task != null){
                    if (!task.getStatus().equals("0") && !task.getStatus().equals("领料")){
                        return SqlResult.error("替换订单已经开始生产，不能再编辑",null);
                    }
                    if (!StringUtils.isEmpty(task.getTaskStatus()) && !task.getTaskStatus().equals("已排产")){
                        return SqlResult.error("替换订单已经开始"+task.getTaskStatus()+"，不能再编辑",null);
                    }

                    taskList.add(task);
                    if (task.getScaleId() != null){
                        mesScalesOrderItemService.addCount(task.getScaleId(),-task.getQuantity().doubleValue(),0.0,0.0);
                    }
                }
            }
            int a = getBaseMapper().deleteProTaskByTaskIds(taskIds);
            if (a > 0){
                for (int i = 0;i < taskList.size();i++){
                    //跟新销售订单完成数量
                    ProTask task = taskList.get(i);
                    task.setQuantity(BigDecimal.valueOf(0)); //已经删除数量为0
                    proWorkorderService.setStatusAfterTaskChange(task);
                }
            }

            return a > 0? SqlResult.error(null,null):SqlResult.error(this.getClass().toString(),null);

        }catch (Exception e){
            e.printStackTrace();
            return SqlResult.error(this.getClass().toString(),null);
        }
    }


    @Override
    public List<ProTask> selectTaskList(Date startDate,Date endDate) {
        return getBaseMapper().selectTaskList(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,startDate),DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,endDate));
    }

    /**
     * 查询打印数据(产品，流程，机台)
     * @param taskId 生成任务id
     * @return
     */
    @Override
    public ProTask selectPrintData(String taskId) {
        //查询生产任务
        ProTask proTask = getBaseMapper().selectProTaskByTaskId(Long.valueOf(taskId));
        return proTask;
    }




    /**
     * 查询当天排产任务
     * @param proTask
     * @return
     */
    @Override
    public List<ProTask> selectTimeOfTheDayProTask(ProTask proTask) {

        return getBaseMapper().selectTimeOfTheDayProTask(proTask);
    }


    /**
     * 打印批号 年月 + 当月流水号
     * @return
     */
    @Override
    public String selectPrintBatchNo() {
        QueryWrapper<ProTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("batch_no");
        queryWrapper.last("limit 1");
        ProTask task = getOne(queryWrapper);
        String dateStr = DateUtils.dateTimeNow();
        String bacthNoFirst = dateStr.substring(2,6);
        if (task == null || task.getBatchNo() == null){
            return bacthNoFirst+"001";
        }else {
            if (task.getBatchNo().startsWith(bacthNoFirst)){
                Integer no = Integer.valueOf(task.getBatchNo().substring(bacthNoFirst.length()))+1;
                if (no < 10){
                    return bacthNoFirst+"00"+no;
                }else if (no < 100){
                    return bacthNoFirst+"0"+no;
                }else {
                    return bacthNoFirst+no;
                }
            }else {
                return bacthNoFirst+"001";
            }
        }
    }

    /**
     *  根据采集的数据修改 排产任务状态
     * @param recLnspectionRecord
     * @return
     */
    public String updateFromRecLnspectionRecord(RecLnspectionRecord recLnspectionRecord){
        if (recLnspectionRecord.getTaskId() == null){
            return  "任务【taskId】不能为空！";
        }
        if (recLnspectionRecord.getProcessesId() == null){
            return  "工序【processesId】不能为空！";
        }
        //更加采集数据修改任务信息
        ProTask proTask = new ProTask();
        proTask.setTaskId(Long.valueOf(recLnspectionRecord.getTaskId()));
        QueryWrapper<ProTask> proTaskQueryWrapper = new QueryWrapper<>(proTask);
        proTask = getOne(proTaskQueryWrapper);
        if (proTask == null){
            return "任务已经被删除！";
        }

        boolean isNeedUpdate = false;
        if (proTask.getStatus() == null){
            ProRouteProcess proRouteProcess = proRouteProcessService.getById(recLnspectionRecord.getProcessesId());
            proTask.setStatus(proRouteProcess.getProcessId().toString());
            proTask.setColorCode(proRouteProcess.getColorCode());
            isNeedUpdate = true;
        }
        if (proTask.getStartTime() == null){
            proTask.setStartTime(new Date());
            isNeedUpdate = true;
        }
        if (StringUtils.isEmpty(proTask.getBatchNo())){
            proTask.setBatchNo(selectPrintBatchNo());
            isNeedUpdate = true;
        }
        if(isNeedUpdate){
           updateById(proTask);
        }
        return null;
    }

    @Override
    public String updateFromProTaskDeviceProcess(ProTaskDeviceProcess taskDeviceProcess) {
        if (taskDeviceProcess.getTaskId() == null){
            return  "任务【taskId】不能为空！";
        }
        if (taskDeviceProcess.getProcessId() == null){
            return  "工序【processesId】不能为空！";
        }
        //更加采集数据修改任务信息
        ProTask proTask = getById(taskDeviceProcess.getTaskId());
        if (proTask == null){
            return "任务已经被删除！";
        }

        boolean isNeedUpdate = false;
        if (proTask.getStatus() == null){
            ProRouteProcess proRouteProcess = proRouteProcessService.getById(taskDeviceProcess.getProcessId());
            proTask.setStatus(proRouteProcess.getProcessId().toString());
            proTask.setColorCode(proRouteProcess.getColorCode());
            proTask.setProcessName(taskDeviceProcess.getProcessName());
            isNeedUpdate = true;
        }

        if (proTask.getStartTime() == null){
            proTask.setStartTime(new Date());
            isNeedUpdate = true;
        }

        if (StringUtils.isEmpty(proTask.getBatchNo())){
            proTask.setBatchNo(selectPrintBatchNo());
            isNeedUpdate = true;
        }

        if(isNeedUpdate){
            updateById(proTask);
        }
        return null;
    }



    public List<JSONObject> selectCountProTask(String startTime, String endTime){
        return getBaseMapper().selectCountProTask(startTime,endTime);
    };
    public List<JSONObject> selectBomFromItem(List<Long> itemIds){
        if (itemIds == null || itemIds.size() == 0){
            return null;
        }
        return getBaseMapper().selectBomFromItem(itemIds);
    };


    /**
     *
     */
    public void updateQuantityNotInAndTaskStatus(List<Long> taskIds){
        getBaseMapper().updateQuantityNotInAndTaskStatus(taskIds);
        proWorkorderService.updateStatusFromTaskId(taskIds);
    }



    //监听入库记录变化
    @SQLListenerInterface(tableName = "wm_item_recpt_line",listerType = {SQLListenerType.BeforeAll})
    public SqlResult wmItemRecptLineListener(SQLListenerType type, WmItemRecptLine oldObj, WmItemRecptLine newObj) {
        try {
            //修改排产任务未入库数量
            if (oldObj != null
                    && newObj != null
                    && oldObj.getTaskId() != null
                    && newObj.getTaskId() != null
                    && oldObj.getTaskId().longValue() == newObj.getTaskId().longValue()

            ){
                ProTask proTask = getById(newObj.getTaskId());
                if(proTask == null){
                    return SqlResult.error("入库记录关联的排产信息已经被删除，无法入库",null);
                }
                if (proTask.getTaskStatus().equals(ProTask.taskStatusDefect) || proTask.getTaskStatus().equals(ProTask.taskStatusUnqualified)){
                    return SqlResult.error(proTask.getTaskStatus()+" 状态下的物料不允许入库",null);
                }
                if (proTask.getQuantityNotIn() == null){
                    proTask.setQuantityNotIn(proTask.getQuantity());
                }
                float aoun =  proTask.getQuantityNotIn().floatValue() - newObj.getQuantityRecived().floatValue() + oldObj.getQuantityRecived().floatValue();
                proTask.setQuantityNotIn(BigDecimal.valueOf(aoun));

                if (!proTask.getTaskStatus().equals(ProTask.taskStatusAllInWarehouse)){
                    if (aoun < proTask.getQuantity().floatValue()){
                        if (aoun < 10){
                            proTask.setTaskStatus(ProTask.taskStatusAllInWarehouse);
                        }else {
                            proTask.setTaskStatus(ProTask.taskStatusInWarehouse);
                        }
                    }else {
                        proTask.setTaskStatus(ProTask.taskStatusFinish);
                    }
                }
                boolean falg = updateById(proTask);
                if (!falg){
                    return SqlResult.error(this.getClass().toString()+":updateProTask",null);
                }
                falg = proWorkorderService.setStatusAfterTaskChange(proTask);
                if (!falg){
                    return SqlResult.error(proWorkorderService.getClass().toString()+":setStatusAfterTaskChange",null);
                }
            }else {
                if (oldObj != null && oldObj.getTaskId() != null){
                    ProTask proTask = getById(oldObj.getTaskId());
                    if (proTask == null){
                        return SqlResult.error("入库产品管理的排产任务已经被删除",null);
                    }
                    if (proTask.getTaskStatus().equals(ProTask.taskStatusDefect) || proTask.getTaskStatus().equals(ProTask.taskStatusUnqualified)){
                        return SqlResult.error(proTask.getTaskStatus()+" 状态下的物料不允许入库",null);
                    }
                    if (proTask.getQuantityNotIn() == null){
                        proTask.setQuantityNotIn(proTask.getQuantity());
                    }
                    float aoun = proTask.getQuantityNotIn().floatValue() + oldObj.getQuantityRecived().floatValue();
                    proTask.setQuantityNotIn(BigDecimal.valueOf(aoun));
                    if (!proTask.getTaskStatus().equals(ProTask.taskStatusAllInWarehouse)){
                        if (aoun < proTask.getQuantity().floatValue()){
                            if (aoun < 10){
                                proTask.setTaskStatus(ProTask.taskStatusAllInWarehouse);
                            }else {
                                proTask.setTaskStatus(ProTask.taskStatusInWarehouse);
                            }
                        }else {
                            proTask.setTaskStatus(ProTask.taskStatusFinish);
                        }
                    }
                    boolean falg = updateById(proTask);
                    if (!falg){
                        return SqlResult.error(this.getClass().toString()+":updateProTask",null);
                    }
                    falg = proWorkorderService.setStatusAfterTaskChange(proTask);
                    if (!falg){
                        return SqlResult.error(proWorkorderService.getClass().toString()+":setStatusAfterTaskChange",null);
                    }
                }

                if (newObj != null && newObj.getTaskId() != null){
                    ProTask proTask = getById(newObj.getTaskId());
                    if (proTask.getTaskStatus().equals(ProTask.taskStatusDefect) || proTask.getTaskStatus().equals(ProTask.taskStatusUnqualified)){
                        return SqlResult.error(proTask.getTaskStatus()+" 状态下的物料不允许入库",null);
                    }
                    if (proTask.getQuantityNotIn() == null){
                        proTask.setQuantityNotIn(proTask.getQuantity());
                    }
                    float aoun = proTask.getQuantityNotIn().floatValue() - newObj.getQuantityRecived().floatValue();
                    proTask.setQuantityNotIn(BigDecimal.valueOf(aoun));
                    if (!proTask.getTaskStatus().equals(ProTask.taskStatusAllInWarehouse)){
                        if (aoun < proTask.getQuantity().floatValue()){
                            if (aoun < 10){
                                proTask.setTaskStatus(ProTask.taskStatusAllInWarehouse);
                            }else {
                                proTask.setTaskStatus(ProTask.taskStatusInWarehouse);
                            }
                        }else {
                            proTask.setTaskStatus(ProTask.taskStatusFinish);
                        }
                    }
                    boolean falg = updateById(proTask);
                    if (!falg){
                        return SqlResult.error(this.getClass().toString()+":updateProTask",null);
                    }
                    falg = proWorkorderService.setStatusAfterTaskChange(proTask);
                    if (!falg){
                        return SqlResult.error(proWorkorderService.getClass().toString()+":setStatusAfterTaskChange",null);
                    }
                }
            }

        }catch (Exception e){
            e.printStackTrace();
            return SqlResult.error(this.getClass().toString(),e);
        }
        return SqlResult.ok(null,null);
    }

}
